
module RAS #(
	parameter BUFFER_SIZE=16
)(
	input logic cpu_clk,
	input logic cpu_rst_n,
	input logic clear,
	input logic ras_up1,
	input logic ras_up2,
	input logic ras_down1,
	input logic ras_down2,
	input logic we,
	input logic [31: 0] addr,
	input logic re,
	output logic [31: 0] out_addr
);
	logic [31: 0] douta;
	logic [$clog2(BUFFER_SIZE)-1: 0] top, topp1, retire_top, next_retire_top;
	logic next_clear;
	SDPRAM #(
		.WORD_WIDTH(32),
		.DEPTH(BUFFER_SIZE),
		.INIT_PARAM("bfc00000,bfc00000,bfc00000,bfc00000,bfc00000,bfc00000,bfc00000,bfc00000,bfc00000,bfc00000,bfc00000,bfc00000,bfc00000,bfc00000,bfc00000,bfc00000"),
		// .INIT_FILE("init_ras.mem"),
		.ADDR_WIDTH($clog2(BUFFER_SIZE))
	) ras_buffer(
		.clk(cpu_clk),
		.ena(we),
		.addra(top),
		.wea(we),
		.dina(addr),
		.douta(douta),
		.enb(1'b1),
		.addrb(topp1),
		.doutb(out_addr)
	);
	
	assign topp1 = top - 1;
	assign next_retire_top = retire_top + ras_up1 + ras_up2 - ras_down1 - ras_down2;
	always_ff @(posedge cpu_clk)begin
		next_clear <= clear;
		if(cpu_rst_n == 1'b0)begin
			top <= 0;
			retire_top <= 0;
		end
		else if(next_clear)begin
			top <= next_retire_top;
			retire_top <= next_retire_top;
		end
		else begin
			retire_top <= next_retire_top;
			if(we)begin
				top <= top + 1;
			end
			if(re)begin
				top <= topp1;
			end
		end
	end
endmodule